package util

import (
	"github.com/tendermint/tendermint/memcask/data"
	"github.com/tendermint/tendermint/memcask/errors"
	"hash/crc32"
	"os"
)

func ReadFileByOffset(f *os.File, offset int64) ([]byte, error) {
	size, err := GetFileSize(f)
	if err != nil {
		return nil, err
	}

	var headerSize int
	if int(offset)+data.DataHeaderSize <= size {
		headerSize = data.DataHeaderSize
	} else {
		headerSize = size - int(offset)
	}

	headerBuf := make([]byte, headerSize)

	// header
	_, err = f.ReadAt(headerBuf, offset)
	if err != nil {
		return nil, err
	}

	dataHeader, realHeaderSize := data.DecodeHeader(headerBuf)
	if err != nil {
		return nil, err
	}

	offset += int64(realHeaderSize)
	dataSize := dataHeader.KeySize + dataHeader.ValSize
	dataBuf := make([]byte, dataSize)

	_, err = f.ReadAt(dataBuf, offset)
	if err != nil {
		return nil, err
	}

	crc := crc32.ChecksumIEEE(append(headerBuf[5:realHeaderSize], dataBuf...))
	if crc != dataHeader.Crc {
		return nil, errors.ErrCrcNotValid
	}
	return dataBuf[dataHeader.KeySize:], nil
}
